<template>
	<div class="json-schema-editor">
		<template v-if="props.root && isSensor">
			<sensor-header v-bind="props" />
		</template>
		<template v-else-if="props.root">
			<base-header v-bind="props" />
		</template>
		<div class="data-row">
			<!-- 添加/删除操作列 -->
			<div class="ant-col-setting" v-if="!disabled">
				<!-- 添加 -->
				<el-tooltip popper-class="jsonform-tooltip" :show-after="1000" v-if="isObject">
					<template #content>{{ local["add_child_node"] }}</template>
					<el-button link class="plus-icon iconfont iconbx-plus" @click="addChildNode.visible = true" />
				</el-tooltip>
				<div v-else class="empty-btn"></div>

				<!-- 删除 -->
				<el-popconfirm title="是否删除该数据？" popper-class="jsonform-tooltip" v-if="!root && !isItem" @confirm="removeNode">
					<template #reference>
						<el-button link class="close-icon ant-btn-icon-only iconfont iconbx-minus" />
					</template>
				</el-popconfirm>
				<!-- <el-tooltip popper-class="jsonform-tooltip" :show-after="1000" v-if="!root && !isItem">
					<template #content>{{ local["remove_node"] }}</template>
					<el-button link class="close-icon ant-btn-icon-only iconfont iconbx-minus" @click="removeNode" />
				</el-tooltip> -->
				<el-button
					v-if="
						pickValueKeyCopy != dataKey ||
						pickValueTypeCopy != pickValue.type ||
						pickValueTitleCopy != pickValue.title ||
						(pickValue.type != 'object' && !!dataValue && dataValueCopy != dataValue)
					"
					link
					class="iconfont iconcirclecheckfull"
					style="color: green"
					@click="
						() => {
							// props.jsonValue[dataKey] = dataValue;
							// pickValueKeyCopy = dataKey;
							// pickValueTypeCopy = pickValue.type;
							// pickValueTitleCopy = pickValue.title;
							// dataValueCopy = dataValue;
							mittBus.emit('addJsonValue');
						}
					"
				/>
				<div v-else class="empty-btn"></div>
			</div>

			<!-- schema 字段key -->
			<div class="ant-col-name">
				<div class="ant-col-name-c pl-1" :style="{ marginLeft: 10 * deep + 'px' }">
					<el-button
						v-if="pickValue.type === 'object'"
						link
						@click="hidden = !hidden"
						:class="`iconfont ${hidden ? 'iconbx-caret-right' : 'iconbx-caret-down'}`"
					/>
					<span v-else style="display: inline-block; width: 25px"></span>
					<template v-if="!root">
						<!-- 必填选项 -->
						<el-input v-model="dataKey" class="ant-col-name-input" @blur="onInputName" placeholder="标识必须是字母开头" />
					</template>
					<template v-else>{{ pickValue.title }}</template>
				</div>
			</div>

			<!-- schema type类型 -->
			<div class="ant-col-type">
				<el-select v-if="!root" v-model="pickValue.type" :disabled="disabled" class="ant-col-type-select" @change="onChangeType">
					<el-option :key="key" v-for="(name, key) in TYPE_NAME" :value="key" :label="name">{{ name }}</el-option>
				</el-select>
			</div>

			<!-- schema title标题 -->
			<div class="ant-col-title">
				<el-input
					v-if="!root"
					v-model="pickValue.title"
					class="ant-col-title"
					:placeholder="local['title']"
					:disabled="disabled"
				/>
			</div>

			<!-- profile 扩展数据列 -->
			<div class="ant-col-values truncate" :title="$t('jsonschemaform.tip_title.data')">
				<template v-if="!pickValue.properties">
					<!-- 扩展列数据显示：传感器时，不能编辑 -->
					<template v-if="isSensor">
						<el-tooltip popper-class="jsonform-tooltip" :show-after="1000">
							<template #content>
								<div>
									<span
										class="cursor-pointer iconfont iconbx-copy-alt"
										v-copy="typeof dataValue == 'string' ? dataValue : JSON.stringify(dataValue)"
									>
										<span class="font-12">{{ $t("jsonschemaform.span.copy") }}</span>
									</span>
									{{ typeof dataValue == "string" ? dataValue : JSON.stringify(dataValue) }}
								</div>
							</template>
							<span type="primary" class="value-text truncate a-link" @click="clickValueIcon(undefined)">{{ dataValue }}</span>
						</el-tooltip>
					</template>

					<!-- 扩展列数据显示：配置 -->
					<template v-else-if="mode == 'conf'">
						<el-select
							v-if="pickKey == 'type' && extType"
							v-model="dataValue"
							@change="changeJsonValue"
							:reserve-keyword="false"
							filterable
							allow-create
							default-first-option
							fit-input-width
							:disabled="disabled"
						>
							<el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value"></el-option>
						</el-select>
						<el-select
							v-else-if="pickKey == 'unit' && extType"
							@change="changeJsonValue"
							v-model="dataValue"
							:reserve-keyword="false"
							filterable
							:filter-method="(value:any) => (unitListKeyword = value)"
							allow-create
							default-first-option
							fit-input-width
							:disabled="disabled"
						>
							<el-option v-for="item in unitListTemporary" :key="item.value" :label="item.label" :value="item.value">
								<div class="flex justify-between items-center">
									<div>{{ item.label }}</div>
									<div class="text-gray-400 font-12">{{ item.value }}</div>
								</div>
							</el-option>
						</el-select>
						<el-input-number
							v-else-if="pickValue.type == 'number'"
							v-model="dataValue"
							:placeholder="`请输入${pickValue.title || pickKey}内容`"
							@input="changeJsonValue"
							:disabled="disabled"
						/>
						<div v-else-if="pickValue.type == 'object'"></div>
						<el-input
							v-else
							v-model="dataValue"
							:placeholder="`请输入${pickValue.title || pickKey}内容`"
							@input="changeJsonValue"
							:disabled="disabled"
						/>
					</template>

					<!-- 扩展列数据显示 -->
					<template v-else>
						<el-tooltip popper-class="jsonform-tooltip" :show-after="1000" :content="JSON.stringify(dataValue)">
							<span class="value-text">{{ dataValue }}</span>
						</el-tooltip>
					</template>
				</template>
			</div>
			<!-- 变量配置 -->
			<div class="ant-col-param truncate" v-if="isSensor">
				<template v-if="pickValue.type == 'object'">
					<!-- 数据类型是json时不处理 -->
				</template>
				<template v-else>
					<el-tooltip popper-class="jsonform-tooltip" placement="bottom-start" :show-after="1000">
						<template #content>
							<div>
								<span class="cursor-pointer iconfont iconbx-copy-alt" v-copy="JSON.stringify(dataParam, null, 2)">
									<span class="font-12">{{ $t("jsonschemaform.span.copy") }}</span>
								</span>
								<pre>{{ JSON.stringify(dataParam, null, 2) }}</pre>
							</div>
						</template>
						<span
							type="primary"
							:underline="false"
							class="value-text truncate a-link"
							@click="clickParam()"
							:title="$t('jsonschemaform.tip_title.config')"
						>
							{{ dataParam || "--" }}
						</span>
					</el-tooltip>
				</template>
			</div>
			<!-- profile 扩展数据列 -->
			<div class="ant-col-operate text-center" v-if="isSensor">
				<template v-if="!pickValue.properties">
					<!-- 告警配置 -->
					<el-tooltip popper-class="jsonform-tooltip" :show-after="1000" :content="DataPreview.configAlarm.tooltip">
						<el-link
							type="primary"
							:class="`iconfont ${DataPreview.configAlarm.icon}`"
							@click="clickValueIcon(DataPreview.configAlarm)"
						>
							{{ DataPreview.configAlarm.label }}
						</el-link>
					</el-tooltip>
					<!-- 位置信息 -->
					<el-tooltip
						popper-class="jsonform-tooltip"
						v-if="pickValue.type == DataPreview.location.type"
						:show-after="1000"
						:content="DataPreview.location.tooltip"
					>
						<el-link
							type="primary"
							:class="`iconfont ${DataPreview.location.icon}`"
							@click="clickValueIcon(DataPreview.location)"
						>
							{{ DataPreview.location.label }}
						</el-link>
					</el-tooltip>
					<!-- 视频信息 -->
					<el-tooltip
						popper-class="jsonform-tooltip"
						v-else-if="pickValue.type == DataPreview.video.type"
						:show-after="1000"
						:content="DataPreview.video.tooltip"
					>
						<el-link type="primary" :class="`iconfont ${DataPreview.video.icon}`" @click="clickValueIcon(DataPreview.video)">
							{{ DataPreview.video.label }}
						</el-link>
					</el-tooltip>

					<!-- 网页信息 -->
					<el-tooltip
						popper-class="jsonform-tooltip"
						v-else-if="pickValue.type == DataPreview.web.type"
						:show-after="1000"
						:content="DataPreview.web.tooltip"
					>
						<el-link type="primary" :class="`iconfont ${DataPreview.web.icon}`" @click="clickValueIcon(DataPreview.web)">
							{{ DataPreview.web.label }}
						</el-link>
					</el-tooltip>

					<!-- 历史图片 -->
					<el-tooltip
						popper-class="jsonform-tooltip"
						v-else-if="pickValue.type == DataPreview.img.type"
						:show-after="1000"
						:content="DataPreview.img.tooltip"
					>
						<el-link type="primary" :class="`iconfont ${DataPreview.img.icon}`" @click="clickValueIcon(DataPreview.img)">
							{{ DataPreview.img.label }}
						</el-link>
					</el-tooltip>
					<!-- 文件 -->
					<el-tooltip
						popper-class="jsonform-tooltip"
						v-else-if="pickValue.type == DataPreview.file.type"
						:show-after="1000"
						:content="DataPreview.file.tooltip"
					>
						<el-link type="primary" :class="`iconfont ${DataPreview.file.icon}`" @click="clickValueIcon(DataPreview.file)">
							{{ DataPreview.file.label }}
						</el-link>
					</el-tooltip>

					<!-- 列表、图表信息 -->
					<el-tooltip v-else-if="pickValue.type != 'object'" :show-after="1000" :content="DataPreview.historyChart.tooltip">
						<el-link
							type="primary"
							:class="`iconfont ${DataPreview.historyChart.icon}`"
							@click="clickValueIcon(DataPreview.historyChart)"
						>
							{{ DataPreview.historyChart.label }}
						</el-link>
					</el-tooltip>
					<!-- 字典配置 -->
					<el-tooltip
						v-if="props.deep == 1"
						popper-class="jsonform-tooltip"
						:show-after="1000"
						:content="DataPreview.dict.tooltip"
					>
						<el-link type="primary" :class="`iconfont ${DataPreview.dict.icon}`" @click="clickValueIcon(DataPreview.dict)">
							{{ DataPreview.dict.label }}
						</el-link>
					</el-tooltip>
				</template>
				<template v-else-if="!props.root && pickValue.properties">
					<!-- 告警配置 -->
					<el-tooltip popper-class="jsonform-tooltip" :show-after="1000" :content="DataPreview.configAlarm.tooltip">
						<el-link
							type="primary"
							:class="`iconfont ${DataPreview.configAlarm.icon}`"
							@click="clickValueIcon(DataPreview.configAlarm)"
						>
							{{ DataPreview.configAlarm.label }}
						</el-link>
					</el-tooltip>
					<!-- 字典配置 -->
					<el-tooltip
						v-if="props.deep == 1"
						popper-class="jsonform-tooltip"
						:show-after="1000"
						:content="DataPreview.dict.tooltip"
					>
						<el-link type="primary" :class="`iconfont ${DataPreview.dict.icon}`" @click="clickValueIcon(DataPreview.dict)">
							{{ DataPreview.dict.label }}
						</el-link>
					</el-tooltip>
				</template>
			</div>
		</div>
		<template v-if="isArray">
			<JsonSchemaForm
				:value="{ items: pickValue.items }"
				:deep="deep + 1"
				:disabled="disabled"
				isItem
				:root="false"
				:path="`${path ? path + '.' : ''}items`"
				class="children"
				:lang="lang"
				:extType="extType"
				:jsonValue="jsonValue"
				:jsonParam="jsonParam"
				:custom="custom"
				:is-sensor="isSensor"
				:mode="mode"
			/>
		</template>
		<template v-if="!hidden && pickValue.properties && !isArray">
			<JsonSchemaForm
				v-for="(item, key) in pickValue.properties"
				:value="{ [key]: item }"
				:parent="pickValue"
				:key="item"
				:deep="deep + 1"
				:extType="extType"
				:root="false"
				:path="`${path ? path + '.' : ''}${key}`"
				class="children"
				:lang="lang"
				:jsonValue="jsonValue"
				:jsonParam="jsonParam"
				:custom="custom"
				:is-sensor="isSensor"
				:mode="mode"
				:disabled="disabled"
			/>
		</template>
		<el-dialog
			v-model:visible="modalVisible"
			v-if="modalVisible"
			:title="local['adv_setting']"
			:maskClosable="false"
			:okText="local['ok']"
			:cancelText="local['cancel']"
			width="800px"
			@ok="handleOk"
			wrapClassName="json-schema-editor-advanced-modal"
		>
			<h3>{{ local["base_setting"] }}</h3>
			<el-form :model="advancedValue" class="ant-advanced-search-form">
				<el-row :gutter="6">
					<el-col :span="8" v-for="(item, key) in advancedValue" :key="key">
						<el-form-item>
							<span>{{ local[key] }}</span>
							<el-input-number
								v-model="advancedValue[key]"
								v-if="advancedAttr[key].type === 'integer' || advancedAttr[key].type === 'number'"
								style="width: 100%"
								:placeholder="local[key]"
							/>
							<span v-else-if="advancedAttr[key].type === 'boolean'" style="display: inline-block; width: 100%">
								<el-switch v-model:checked="advancedValue[key]" />
							</span>
							<el-input
								@blur="changeEnumValue"
								:default-value="enumText"
								autosize
								type="textarea"
								:rows="2"
								v-else-if="key === 'enum'"
								:placeholder="local['enum_msg']"
							></el-input>
							<el-select
								v-else-if="advancedAttr[key].type === 'array'"
								v-model="advancedValue[key]"
								style="width: 100%"
								:placeholder="local[key]"
							>
								<!-- <el-option value="" :label="local["nothing"] "/> -->
								<el-option :value="t" :label="t" :key="t" v-for="t in advancedAttr[key].enums" />
							</el-select>
							<el-input v-model="advancedValue[key]" v-else style="width: 100%" :placeholder="local[key]" />
						</el-form-item>
					</el-col>
				</el-row>
			</el-form>
			<h3 v-show="custom">{{ local["add_custom"] }}</h3>
			<el-form class="ant-advanced-search-form" v-show="custom">
				<el-row :gutter="6">
					<el-col :span="8" v-for="item in customProps" :key="item.key">
						<el-form-item :label="item.key">
							<el-input v-model="item.value" style="width: calc(100% - 30px)" />
							<el-button link @click="removeCustomNode(item.key)" style="width: 30px"> 删除 </el-button>
						</el-form-item>
					</el-col>
					<el-col :span="8" v-show="addProp.key != undefined">
						<el-form-item>
							<template #label><el-input v-model="addProp.key" style="width: 100px" /></template>
							<el-input v-model="addProp.value" style="width: 100%" />
						</el-form-item>
					</el-col>
					<el-col :span="8">
						<el-form-item>
							<el-button link @click="confirmAddCustomNode(addProp)" v-if="customing"> 添加 </el-button>
							<el-tooltip popper-class="jsonform-tooltip" :show-after="1000" :title="local['add_custom']" v-else>
								<el-button link @click="addCustomNode"> 添加 </el-button>
							</el-tooltip>
						</el-form-item>
					</el-col>
				</el-row>
			</el-form>
			<h3>{{ local["preview"] }}</h3>
			<pre style="width: 100%">{{ completeNodeValue }}</pre>
		</el-dialog>

		<DialogBox
			:title="$t('jsonschemaform.dialog_title.add')"
			:visible="addChildNode.visible"
			:footerLabel="[$t('jsonschemaform.dialog_footerlabel.close'), $t('jsonschemaform.dialog_footerlabel.save')]"
			width="680px"
			@confirm="() => addChild()"
			@close="addChildNode.visible = false"
		>
			<el-form
				:model="addChildNode.formData"
				ref="addChildNodeForm"
				:rules="{
					key: [{ required: true, message: $t('jsonschemaform.form_rule.key'), trigger: 'change' }]
				}"
				label-width="100"
			>
				<el-form-item :label="$t('jsonschemaform.form_label.label')" prop="label">
					<el-input v-model="addChildNode.formData.label"></el-input>
				</el-form-item>
				<el-form-item :label="$t('jsonschemaform.form_label.key')" prop="key">
					<el-input v-model="addChildNode.formData.key"></el-input>
				</el-form-item>
				<el-form-item :label="$t('jsonschemaform.form_label.type')" prop="type">
					<el-select v-model="addChildNode.formData.type">
						<el-option :key="key" v-for="(name, key) in TYPE_NAME" :value="key" :label="name">{{ name }}</el-option>
					</el-select>
				</el-form-item>
				<el-form-item :label="$t('jsonschemaform.form_label.value')" prop="value">
					<el-input v-model="addChildNode.formData.value" :disabled="addChildNode.formData.type == 'object'"></el-input>
				</el-form-item>
			</el-form>
		</DialogBox>
	</div>
</template>
<script setup lang="ts">
import DialogBox from "@/components/DialogBox";
import { DataPreview, DataPreviewItem } from "@/enums/dataPreview";
import mittBus from "@/utils/mittBus";
import jsonpath from "jsonpath";
import { JsonSchemaEmitParam } from "./interface/jsonschema";
import LocalProvider from "./LocalProvider/index";
import { TYPE, TYPE_LIST, TYPE_NAME, UNIT_LIST } from "./type/type";
import { isNull, renamePropertyAndKeepKeyPrecedence } from "./util";
import BaseHeader from "./components/BaseHeader.vue";
import SensorHeader from "./components/SensorHeader.vue";
import "./index.scss";
import { SchemaInfo } from "./interface";
import { getCurrentInstance, ComputedRef, ComponentInternalInstance } from "vue";
import { assJsonpathData } from "../../utils/util";
const props = defineProps({
	value: {
		type: Object,
		required: true
	},
	disabled: {
		//name不可编辑，根节点name不可编辑,数组元素name不可编辑
		type: Boolean,
		default: false
	},
	isItem: {
		//是否数组元素
		type: Boolean,
		default: false
	},
	deep: {
		// 节点深度，根节点deep=0
		type: Number,
		default: 0
	},
	root: {
		//是否root节点
		type: Boolean,
		default: true
	},
	parent: {
		//父节点
		type: Object,
		default() {
			return {};
		}
	},
	custom: {
		//enable custom properties
		type: Boolean,
		default: false
	},
	lang: {
		// i18n language
		type: String,
		default: "zh_CN"
	},
	path: {
		type: String,
		default: ""
	},
	// isEditer: {
	// 	//编辑模式：编辑模式显示完整编辑项，只读模式只显示节点label+数据内容
	// 	type: Boolean,
	// 	default: true
	// },
	extType: {
		//扩展Type选项：扩展key=type的数据类型选择
		type: Boolean,
		default: false
	},
	mode: {
		//页面模式，定义schema=conf，回填内容=preview
		type: String,
		default: "conf"
	},
	isSensor: {
		//是否是变量模型
		type: Boolean,
		default: false
	},
	jsonValue: {
		//扩展的json字段值
		type: Object,
		default() {
			return {};
		}
	},
	jsonParam: {
		//扩展的参数
		type: Object,
		default() {
			return {};
		}
	}
});
// const props = withDefaults(
// 	defineProps({},
// 	{
// 		value: {},
// 		disabled: false,
// 		disabledType: false,
// 		isItem: false,
// 		root: true,
// 		custom: false,
// 		parent: () => {},
// 		lang: "zh_CN",
// 		path: "",
// 		deep: 0
// 	}
// );
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const dataValue = ref<any>();
const dataParam = ref<any>();
const typeList = ref<{ label: string; value: string }[]>(TYPE_LIST);
const unitList = ref<{ label: string; value: string }[]>(UNIT_LIST);
const unitListKeyword = ref("");
let unitListTemporary = computed(() => {
	if (unitListKeyword.value === "") {
		return unitList.value;
	} else {
		return unitList.value.filter((item: any) => {
			return (
				String(item.label).toUpperCase().includes(unitListKeyword.value.toUpperCase()) ||
				String(item.value).toUpperCase().includes(unitListKeyword.value.toUpperCase())
			);
		});
	}
});
onMounted(() => {
	initDataFormJsonValue();
	dataValueCopy.value = dataValue.value;
});
watch(
	() => props.jsonValue,
	() => {
		initDataFormJsonValue();
	},
	{ deep: true }
);
const initDataFormJsonValue = () => {
	if (props.path) {
		if (props.deep == 1) {
			dataValue.value = jsonpath.value(props.jsonValue, assJsonpathData(props.path, "$"));
		} else {
			dataValue.value = jsonpath.value(props.jsonValue, assJsonpathData(props.path, "$.."));
		}
		dataParam.value = jsonpath.value(props.jsonParam, assJsonpathData(props.path, "$.."));
	}
	//根据内容自动更新schema类型
	// if (typeof dataValue.value == "number") {
	// 	pickValue.value.type = "number";
	// }
	//根据schema，强制更新数值
	// if (pickValue.value.type == "number") {
	// 	let val = Number(dataValue.value);
	// 	dataValue.value = isNaN(val) ? 0 : val;
	// 	//强制更新profile内容，避免页面未做编辑
	// 	jsonpath.value(props.jsonValue, assJsonpathData(props.path, "$.."), dataValue.value);
	// }
};
const clickParam = () => {
	if (props.disabled) return;
	mittBus.emit("clickSensorParam", props.path);
};
const clickValueIcon = (type?: DataPreviewItem) => {
	if (!type) {
		let dp = Object.values(DataPreview).find(item => pickValue.value.type == item.type);
		type = dp;
	}

	let param: JsonSchemaEmitParam = {
		dataPath: props.path,
		dataType: type?.type || DataPreview.historyChart.type,
		dataKey: dataKey.value,
		dataValue: dataValue.value,
		schemaInfo: pickValue.value
	};
	mittBus.emit("clickValueIcon", param);
};
const changeJsonValue = (val: any) => {
	if (props.deep > 0 && props.path != dataKey.value) {
		jsonpath.value(props.jsonValue, assJsonpathData(props.path, "$.."), val);
	} else {
		props.jsonValue[dataKey.value] = val;
	}
};
const removeJsonValueNode = (key: string) => {
	if (key) {
		let str = "";
		props.path.split(".").map((endItem: any) => {
			str += `['${endItem}']`;
		});
		jsonpath.query(props.jsonValue, assJsonpathData(props.path, "$..")).length && eval(`delete props.jsonValue${str}`);
		jsonpath.query(props.jsonParam, assJsonpathData(props.path, "$..")).length && eval(`delete props.jsonParam${str}`);
	}
	if (!props.extType) {
		mittBus.emit("delJsonValue", `${props.path}`);
	} else {
		mittBus.emit("delExtType", `${props.path}`);
	}
};
const renamePropertyAndKeepKeyPrecedenceProfile = ({ oldKey }: { newKey?: string; oldKey: string }) => {
	let ppath = props.path.replace(`.${oldKey}`, "");
	//获取原来节点
	let oldNode = jsonpath.query(props.jsonValue, assJsonpathData(ppath, "$.."))[0] || {};
	//设置到新节点
	jsonpath.value(props.jsonValue, assJsonpathData(props.path, "$.."), oldNode);
	//删除原节点
	eval(`delete props.jsonValue['${ppath}']`);
	// console.log(JSON.stringify(props.jsonValue, null, 2));
};

const pickValue: ComputedRef<SchemaInfo | any> = computed(() => {
	return Object.values(props.value)[0];
});
const pickKey = computed(() => {
	return Object.keys(props.value)[0];
});
const isObject = computed(() => {
	return pickValue.value?.type === "object";
});
const isArray = computed(() => {
	return pickValue.value.type === "array";
});
const advanced = computed(() => {
	// return TYPE[pickValue.value.type as string];
	let res;
	switch (pickValue.value.type) {
		case "object":
			res = TYPE.object;
			break;
		case "string":
			res = TYPE.object;
			break;
		case "array":
			res = TYPE.object;
			break;
		case "boolean":
			res = TYPE.object;
			break;
		case "integer":
			res = TYPE.object;
			break;
		case "number":
			res = TYPE.object;
			break;
		case "custom":
			res = TYPE.custom;
			break;
	}
	return res;
});
const advancedAttr = computed(() => {
	// return TYPE[pickValue.value.type].attr;
	let res: any = advanced.value;
	return res?.attr || {};
});
const ownProps = computed(() => {
	return ["type", "title", "properties", "items", "required", ...Object.keys(advancedAttr.value)];
});
const advancedNotEmptyValue = computed(() => {
	const jsonNode = Object.assign({}, advancedValue);
	for (let key in jsonNode) {
		isNull(jsonNode[key]) && delete jsonNode[key];
	}
	return jsonNode;
});
const completeNodeValue = computed(() => {
	const t: any = {};
	const basicValue: any = { ...pickValue.value };
	for (const item of customProps) {
		t[item.key] = item.value;
	}
	_pickDiffKey().forEach(key => delete basicValue[key]);
	return Object.assign({}, basicValue, t, advancedNotEmptyValue.value);
});
const enumText = computed(() => {
	const t = advancedValue["enum"];
	if (!t) return "";
	if (!t.length) return "";
	return t.join("\n");
});

const hidden = ref(false);
const countAdd = ref(1);
const modalVisible = ref(false);
const advancedValue = reactive<{ [key: string]: any }>({});
const addProp = reactive<any>({ key: "", value: "" }); // 自定义属性
const customProps = reactive<any>([]);
const customing = ref(false);
const local = LocalProvider(props.lang);
const dataKey = ref<string>("");
watchEffect(() => {
	dataKey.value = pickKey.value;
});
const onInputName = (e: any) => {
	let newKey = e.target.value;
	// //纯数字key增加key前缀
	// if (!newKey || !isNaN(Number(newKey))) {
	// 	showMsg("节点标识非法，已自动修正", false);
	// 	newKey = "key_" + newKey;
	// }
	const oldKey = pickKey.value;
	if (oldKey === newKey) return;
	// 替换key名
	renamePropertyAndKeepKeyPrecedence(props.parent?.properties, [oldKey, newKey]);
	// 替换profile名
	renamePropertyAndKeepKeyPrecedenceProfile({ oldKey: oldKey, newKey: newKey });

	// required重新设置
	const requireds = props.parent?.required || [];
	const oldIndex = requireds.indexOf(oldKey);
	if (requireds.length > 0 && oldIndex > -1) {
		requireds.splice(oldIndex, 1);
		requireds.push(newKey);
		// eslint-disable-next-line vue/no-mutating-props
		props.parent["required"] = [...new Set(requireds)];
	}
};
const onChangeType = () => {
	if (pickValue.value.type == "object") {
		dataValue.value = {};
		jsonpath.value(props.jsonValue, assJsonpathData(props.path, "$.."), dataValue.value);
	} else if (pickValue.value.type == "string") {
		jsonpath.value(props.jsonValue, assJsonpathData(props.path, "$.."), dataValue.value + "");
	} else if (pickValue.value.type == "number") {
		jsonpath.value(props.jsonValue, assJsonpathData(props.path, "$.."), Number(dataValue.value));
	}
	parseCustomProps();
	// 删除自定义属性
	customProps.forEach((item: any) => {
		delete pickValue.value[item.key];
	});
	customProps.splice(0, customProps.length);

	delete pickValue.value["properties"];
	delete pickValue.value["items"];
	delete pickValue.value["required"];
	delete pickValue.value["format"];
	delete pickValue.value["enum"];

	if (isArray.value) {
		pickValue.value["items"] = { type: "string" };
	}
};
const changeEnumValue = (e: any) => {
	let pickType = pickValue.value.type;
	let value = e.target.value;

	let arr = value.split("\n");

	if (pickType === "string") {
		advancedValue.enum = arr.map((item: any) => item);
	} else {
		if (arr.length === 0 || (arr.length === 1 && arr[0] == "")) {
			advancedValue.enum = null;
		} else {
			advancedValue.enum = arr.map((item: any) => +item);
		}
	}
};
const addChildNode = reactive({
	visible: false,
	formData: { path: "", key: "", type: "string", label: "", value: "" }
});
const addChildNodeForm = ref();
const addChild = () => {
	addChildNodeForm.value.validate((valid: any) => {
		if (valid) {
			addChildNode.visible = false;
			let key = addChildNode.formData.key;
			let type = addChildNode.formData.type;
			addChildNode.formData.path = props.deep > 0 ? `${props.path}.${key}` : `${key}`;
			const node = pickValue.value;
			node.properties || (node["properties"] = {}); // $set(node,'properties',{})
			const nodeProps = node.properties;
			nodeProps[key] = { type: type, title: addChildNode.formData.label || key }; //$set(props,name,{type: type})
			if (props.deep > 0) {
				let node = jsonpath.query(props.jsonValue, assJsonpathData(props.path, "$.."))[0] || {};
				node[key] && (node[key] = "");
			} else {
				props.jsonValue[key] = "";
			}
			let value: any = addChildNode.formData.value;
			if (type == "number") {
				value = addChildNode.formData.value ? Number(addChildNode.formData.value) || 0 : 0;
			}
			if (type == "object") {
				value = {};
			}
			jsonpath.value(props.jsonValue, assJsonpathData(addChildNode.formData.path, "$.."), value);
			if (!props.extType) {
				mittBus.emit("addJsonValue", addChildNode.formData);
			} else {
				mittBus.emit("addExtType", addChildNode.formData);
			}
		}
	});
};
const parseCustomProps = () => {
	let ops = ownProps.value;
	Object.keys(pickValue.value).forEach(key => {
		if (ops.indexOf(key) === -1) {
			confirmAddCustomNode({ key: key, value: pickValue.value[key] });
			// $delete(pickValue.value,key)
		}
	});
};
const addCustomNode = () => {
	// $set(addProp,'key',_joinName())
	// $set(addProp,'value','')
	addProp["key"] = _joinName();
	addProp["value"] = "";
	customing.value = true;
};
const removeCustomNode = (key: string) => {
	customProps.forEach((item: any, index: number) => {
		if (item.key === key) {
			customProps.splice(index, 1);
			return;
		}
	});
};
const confirmAddCustomNode = (prop: { key: string; value: any }) => {
	const p = prop.key ? prop : addProp;
	let existKey = false;
	customProps.forEach((item: any) => {
		if (item.key === p.key) {
			existKey = true;
		}
	});
	if (existKey) return;
	customProps.push(p);
	addProp.key = "";
	addProp.value = "";
	customing.value = false;
};
const removeNode = () => {
	if (!props.parent || !props.parent.type) {
		console.error(proxy?.$t("jsonschemaform.error"));
		return;
	}
	const { properties, required } = props.parent;
	delete properties[pickKey.value];
	if (required) {
		const pos = (required as string[]).indexOf(pickKey.value);
		pos >= 0 && (required as string[]).splice(pos, 1);
		(required as string[]).length === 0 && delete props.parent["required"];
	}
	removeJsonValueNode(pickKey.value);
};
const _joinName = () => {
	return `field_${props.deep}_${countAdd.value++}`;
};

const handleOk = () => {
	modalVisible.value = false;
	for (const key in advancedValue) {
		if (isNull(advancedValue[key])) {
			delete pickValue.value[key];
		} else {
			pickValue.value[key] = advancedValue[key];
		}
	}
	const diffKey = _pickDiffKey();
	diffKey.forEach(key => delete pickValue.value[key]);
	for (const item of customProps) {
		pickValue.value[item.key] = item.value;
	}
};
const _pickDiffKey = () => {
	const keys = Object.keys(pickValue.value);
	return keys.filter(item => ownProps.value.indexOf(item) === -1);
};
const pickValueKeyCopy = ref(dataKey.value);
const pickValueTypeCopy = ref(pickValue.value.type);
const pickValueTitleCopy = ref(pickValue.value.title);
const dataValueCopy = ref(dataValue.value);
</script>
